package com.atm.thirdplt.service.impl;

import com.atm.thirdplt.common.constant.MongoCollConstants;
import com.atm.thirdplt.common.core.domain.entity.AnesAnesthesiaPlan;
import com.atm.thirdplt.common.core.domain.entity.AnesOperationMaster;
import com.atm.thirdplt.common.core.domain.entity.AtmOperationScheduleMid;
import com.atm.thirdplt.common.core.domain.his.*;
import com.atm.thirdplt.common.core.domain.lis.LisLabResult;
import com.atm.thirdplt.common.utils.DateUtils;
import com.atm.thirdplt.common.utils.StringUtils;
import com.atm.thirdplt.dao.mapper.his.HisInfMapper;
import com.atm.thirdplt.dao.mapper.sys.LocalInfMapper;
import com.atm.thirdplt.service.IHisInfService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * his数据处理业务公共实现类(本类适用视图和贵州中联V1.4.4版本、重庆中联0526)
 *
 * @author atm
 */
@Service
public class HisInfServiceImpl implements IHisInfService {

    private static final Logger log = LoggerFactory.getLogger(HisInfServiceImpl.class);

    @Resource
    private HisInfMapper hisInfMapper;

    @Resource
    private LocalInfMapper localInfMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    @Qualifier("primaryJdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<HisUsers> selUsersLocal() {
        return localInfMapper.selUsersLocal();
    }

    @Override
    public List<HisDeptDict> selDeptLocal() {
        return localInfMapper.selDeptLocal();
    }

    @Override
    public void delHisDept() {
        localInfMapper.delHisDept();
    }

    @Override
    public void saveDeptDictMongo(List<HisDeptDict> deptList) {
        mongoTemplate.insert(deptList, MongoCollConstants.HIS_DEPT_DICT);
    }

    @Override
    public void delDeptMongo() {
        mongoTemplate.dropCollection(MongoCollConstants.HIS_DEPT_DICT);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveDept(List<HisDeptDict> list) {
        long start = System.currentTimeMillis();

        jdbcTemplate.batchUpdate("insert into atm_dept_dict(DEPT_CODE, SERIAL_NO, DEPT_NAME, INPUT_CODE)\n" +
                "        values(?,?,?,?)", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getDeptCode());
                ps.setObject(2, list.get(i).getSerialNo());
                ps.setString(3, list.get(i).getDeptName());
                ps.setString(4, list.get(i).getInputCode());
            }
        });

        long end = System.currentTimeMillis();
        log.info("时间差：" + (end - start));
        return 0;
    }

    @Override
    public void uptHisUser(List<HisUsers> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update atm_his_users set user_name=?,user_dept=?,user_job=?,create_date=?," +
                "reserved01=?, CA_USER_ID=? " +
                "where USER_ID=?", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getUserName());
                ps.setString(2, list.get(i).getUserDept());
                ps.setString(3, list.get(i).getUserJob());
                if (list.get(i).getCreateDate() != null) {
                    ps.setTimestamp(4, new Timestamp(list.get(i).getCreateDate().getTime()));
                } else {
                    ps.setTimestamp(4, null);
                }
                ps.setString(5, list.get(i).getReserved01());
                ps.setString(6, list.get(i).getCaUserId());
                ps.setString(7, list.get(i).getUserId());
            }
        });

        long end = System.currentTimeMillis();
        log.info(String.format("del size :%s", list.size()));
        log.info(String.format("del his_users cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void uptHisDept(List<HisDeptDict> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update atm_dept_dict set SERIAL_NO=?,DEPT_NAME=?,INPUT_CODE=?" +
                "where DEPT_CODE=?", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setObject(1, list.get(i).getSerialNo());
                ps.setString(2, list.get(i).getDeptName());
                ps.setString(3, list.get(i).getInputCode());
                ps.setString(4, list.get(i).getDeptCode());
            }
        });

        long end = System.currentTimeMillis();
        log.info(String.format("del size :%s", list.size()));
        log.info(String.format("del his_dept cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void delUserMongo() {
        mongoTemplate.dropCollection(MongoCollConstants.HIS_HIS_USERS);
    }

    @Override
    public void delOperScheMongo(String patientId, String visitId, String startTime, String endTime) {

        Criteria cria =
                Criteria.where("scheduledDateTime").gte(DateUtils.parseDate(startTime)).lte(DateUtils.parseDate(endTime));

        if (StringUtils.isNotEmpty(patientId)) {
            cria.and("patientId").is(patientId);
        }
        if (StringUtils.isNotEmpty(patientId)) {
            cria.and("visitId").is(visitId);
        }

        Query query =
                Query.query(cria);
        mongoTemplate.remove(query, MongoCollConstants.HIS_OPERATION_SCHEDULE);
    }

    @Override
    public void saveOperScheMongo(List<HisOperationSchedule> operList) {
        mongoTemplate.insert(operList, MongoCollConstants.HIS_OPERATION_SCHEDULE);
    }

    private String operStatusChange(String status) {
        // 手术紧急安排状态为急诊时，需要特殊处理
        switch (status) {
            case "N":
                return "0";
            case "G":
                return "0";
            case "C":
                return "-1";
            default:
                return null;
        }
    }

    @Override
    public void uptOperScheLocal(List<HisOperationSchedule> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update atm_operation_schedule set dept_stayed=?," +
                        "bed_no=?, scheduled_date_time=?, operating_room=?, operating_room_no=?, sequence=?, " +
                        "diag_before_operation=?, patient_condition=?, operation_scale=?, emergency_indicator=?, " +
                        "isolation_indicator=?, operating_dept=?, surgeon=?, first_assistant=?, " +
                        "second_assistant=?, " +
                        "third_assistant=?, fourth_assistant=?, anesthesia_method=?, anesthesia_doctor=?, " +
                        "second_anesthesia_doctor=?, third_anesthesia_doctor=?, anesthesia_assistant=?, " +
                        "second_anesthesia_assistant=?, third_anesthesia_assistant=?, " +
                        "fourth_anesthesia_assistant=?, " +
                        "blood_tran_doctor=?, first_operation_nurse=?, second_operation_nurse=?, " +
                        "first_supply_nurse=?, " +
                        "second_supply_nurse=?, third_supply_nurse=?, notes_on_operation=?, req_date_time=?, " +
                        "entered_by=?,state=?,operation_position=?,special_equipment=?,special_infect=?,reserved1=?,reserved2=?,reserved3=? " +
                        "where " +
                        "patient_id=? and visit_id=? and " +
                        "SCHEDULE_ID=?",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, list.get(i).getDeptStayed());
                        ps.setString(2, list.get(i).getBedNo());
                        if (list.get(i).getScheduledDateTime() != null) {
                            ps.setTimestamp(3, new Timestamp(list.get(i).getScheduledDateTime().getTime()));
                        } else {
                            ps.setTimestamp(3, null);
                        }
                        ps.setString(4, list.get(i).getOperatingRoom());
                        ps.setString(5, list.get(i).getOperatingRoomNo());
                        ps.setString(6, list.get(i).getSequence());
                        ps.setString(7, list.get(i).getDiagBeforeOperation());
                        ps.setString(8, list.get(i).getPatientCondition());
                        ps.setString(9, list.get(i).getOperationScale());
                        ps.setObject(10, list.get(i).getEmergencyIndicator());
                        ps.setObject(11, list.get(i).getIsolationIndicator());
                        ps.setString(12, list.get(i).getOperatingDept());
                        ps.setString(13, list.get(i).getSurgeon());
                        ps.setString(14, list.get(i).getFirstAssistant());
                        ps.setString(15, list.get(i).getSecondAssistant());
                        ps.setString(16, list.get(i).getThirdAssistant());
                        ps.setString(17, list.get(i).getFourthAssistant());
                        ps.setString(18, list.get(i).getAnesthesiaMethod());
                        ps.setString(19, list.get(i).getAnesthesiaDoctor());
                        ps.setString(20, list.get(i).getSecondAnesthesiaDoctor());
                        ps.setString(21, list.get(i).getThirdAnesthesiaDoctor());
                        ps.setString(22, list.get(i).getAnesthesiaAssistant());
                        ps.setString(23, list.get(i).getSecondAnesthesiaAssistant());
                        ps.setString(24, list.get(i).getThirdAnesthesiaAssistant());
                        ps.setString(25, list.get(i).getFourthAnesthesiaAssistant());
                        ps.setString(26, list.get(i).getBloodTranDoctor());
                        ps.setString(27, list.get(i).getFirstOperationNurse());
                        ps.setString(28, list.get(i).getSecondOperationNurse());
                        ps.setString(29, list.get(i).getFirstSupplyNurse());
                        ps.setString(30, list.get(i).getSecondSupplyNurse());
                        ps.setString(31, list.get(i).getThirdSupplyNurse());
                        ps.setString(32, list.get(i).getNotesOnOperation());
                        if (list.get(i).getReqDateTime() != null) {
                            ps.setTimestamp(33, new Timestamp(list.get(i).getReqDateTime().getTime()));
                        } else {
                            ps.setString(3, null);
                        }
                        ps.setString(34, list.get(i).getEnteredBy());
                        ps.setString(35, operStatusChange(list.get(i).getStatus()));
                        ps.setString(36, list.get(i).getOperationPosition());
                        ps.setString(37, list.get(i).getSpecialEquipment());
                        ps.setString(38, list.get(i).getSpecialInfect());
                        ps.setString(39, list.get(i).getReserved1());
                        ps.setString(40, list.get(i).getReserved2());
                        ps.setString(41, list.get(i).getReserved3());
                        ps.setString(42, list.get(i).getPatientId());
                        ps.setString(43, list.get(i).getVisitId());
                        ps.setString(44, list.get(i).getScheduleId());


                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("update size : %s", list.size()));
        log.info(String.format("update oper_sche cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void saveOperScheLocal(List<HisOperationSchedule> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into atm_operation_schedule(dept_stayed," +
                        " bed_no, scheduled_date_time, operating_room, operating_room_no, sequence, " +
                        "diag_before_operation, " +
                        "patient_condition, operation_scale, emergency_indicator, isolation_indicator, " +
                        "operating_dept, " +
                        "surgeon, first_assistant, second_assistant, third_assistant, fourth_assistant, " +
                        "anesthesia_method, " +
                        "anesthesia_doctor, second_anesthesia_doctor, third_anesthesia_doctor, " +
                        "anesthesia_assistant, " +
                        "second_anesthesia_assistant, third_anesthesia_assistant, fourth_anesthesia_assistant, " +
                        "blood_tran_doctor, first_operation_nurse, second_operation_nurse, first_supply_nurse, " +
                        "second_supply_nurse, third_supply_nurse, notes_on_operation, req_date_time, entered_by, " +
                        "state,operation_position,special_equipment,special_infect, patient_id, visit_id, " +
                        "schedule_id,reserved1,reserved2,reserved3) " +
                        "        values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                        "?,?,?,?,?,?,?,?)",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, list.get(i).getDeptStayed());
                        ps.setString(2, list.get(i).getBedNo());
                        if (list.get(i).getScheduledDateTime() != null) {
                            ps.setTimestamp(3, new Timestamp(list.get(i).getScheduledDateTime().getTime()));
                        } else {
                            ps.setTimestamp(3, null);
                        }
                        ps.setString(4, list.get(i).getOperatingRoom());
                        ps.setString(5, list.get(i).getOperatingRoomNo());
                        ps.setString(6, list.get(i).getSequence());
                        ps.setString(7, list.get(i).getDiagBeforeOperation());
                        ps.setString(8, list.get(i).getPatientCondition());
                        ps.setString(9, list.get(i).getOperationScale());
                        ps.setObject(10, list.get(i).getEmergencyIndicator());
                        ps.setObject(11, list.get(i).getIsolationIndicator());
                        ps.setString(12, list.get(i).getOperatingDept());
                        ps.setString(13, list.get(i).getSurgeon());
                        ps.setString(14, list.get(i).getFirstAssistant());
                        ps.setString(15, list.get(i).getSecondAssistant());
                        ps.setString(16, list.get(i).getThirdAssistant());
                        ps.setString(17, list.get(i).getFourthAssistant());
                        ps.setString(18, list.get(i).getAnesthesiaMethod());
                        ps.setString(19, list.get(i).getAnesthesiaDoctor());
                        ps.setString(20, list.get(i).getSecondAnesthesiaDoctor());
                        ps.setString(21, list.get(i).getThirdAnesthesiaDoctor());
                        ps.setString(22, list.get(i).getAnesthesiaAssistant());
                        ps.setString(23, list.get(i).getSecondAnesthesiaAssistant());
                        ps.setString(24, list.get(i).getThirdAnesthesiaAssistant());
                        ps.setString(25, list.get(i).getFourthAnesthesiaAssistant());
                        ps.setString(26, list.get(i).getBloodTranDoctor());
                        ps.setString(27, list.get(i).getFirstOperationNurse());
                        ps.setString(28, list.get(i).getSecondOperationNurse());
                        ps.setString(29, list.get(i).getFirstSupplyNurse());
                        ps.setString(30, list.get(i).getSecondSupplyNurse());
                        ps.setString(31, list.get(i).getThirdSupplyNurse());
                        ps.setString(32, list.get(i).getNotesOnOperation());
                        if (list.get(i).getReqDateTime() != null) {
                            ps.setTimestamp(33, new Timestamp(list.get(i).getReqDateTime().getTime()));
                        } else {
                            ps.setString(33, null);
                        }
                        ps.setString(34, list.get(i).getEnteredBy());
                        ps.setString(35, operStatusChange(list.get(i).getStatus()));
                        ps.setString(36, list.get(i).getOperationPosition());
                        ps.setString(37, list.get(i).getSpecialEquipment());
                        ps.setString(38, list.get(i).getSpecialInfect());
                        ps.setString(39, list.get(i).getPatientId());
                        ps.setString(40, list.get(i).getVisitId());
                        ps.setString(41, list.get(i).getScheduleId());
                        ps.setString(42, list.get(i).getReserved1());
                        ps.setString(43, list.get(i).getReserved2());
                        ps.setString(44, list.get(i).getReserved3());
                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("insert size :%s", list.size()));
        log.info(String.format("insert sche_oper_name cost: %s秒", (end - start) / 1000));
    }

    @Override
    public AnesOperationMaster selOperMasterLocal(String patientId, String visitId, String operId) {
        return localInfMapper.selOperMaster(patientId, visitId, operId);
    }

    @Override
    public void uptOperMaster(AnesOperationMaster master) {
        localInfMapper.uptOperMaster(master);
    }

    @Override
    public void uptOperPlain(AnesAnesthesiaPlan plan) {
        localInfMapper.uptOperPlain(plan);
    }

    @Override
    public void intOperMaster(AnesOperationMaster master) {
        localInfMapper.intOperMaster(master);
    }

    @Override
    public void intOperPlain(AnesAnesthesiaPlan plan) {
        localInfMapper.intOperPlain(plan);
    }

    @Override
    public void delPatMasMongo(List<String> patIdList) {
        Query query = Query.query(Criteria.where("patientId").in(patIdList));
        mongoTemplate.remove(query, MongoCollConstants.HIS_PAT_MASTER_INDEX);
    }

    @Override
    public void savePatMasMongo(List<HisPatMasterIndex> list) {
        mongoTemplate.insert(list, MongoCollConstants.HIS_PAT_MASTER_INDEX);
    }

    @Override
    public void delPatInHosMongo(HisPatsInHospital patInHos) {
        Query query =
                Query.query(Criteria.where("patientId").is(patInHos.getPatientId()).and("visitId").is(patInHos.getVisitId()));
        mongoTemplate.remove(query, MongoCollConstants.HIS_PATS_IN_HOSPITAL);
    }

    @Override
    public void savePatInHosMongo(List<HisPatsInHospital> list) {
        mongoTemplate.insert(list, MongoCollConstants.HIS_PATS_IN_HOSPITAL);
    }

    @Override
    public void delOperScheNameMongo(String patId, String visitId, String scheduleId) {
        Query query =
                Query.query(Criteria.where("patientId").is(patId).and("visitId").is(visitId).and("scheduleId").is(scheduleId));
        mongoTemplate.remove(query, MongoCollConstants.HIS_SCHEDULED_OPERATION_NAME);
    }

    @Override
    public void saveOperScheNameMongo(List<HisScheduledOperationName> list) {
        mongoTemplate.insert(list, MongoCollConstants.HIS_SCHEDULED_OPERATION_NAME);
    }

    @Override
    public void delOrdersMongo() {
        Query query = null;
        mongoTemplate.remove(query, LisLabResult.class, MongoCollConstants.HIS_ORDERS);
    }

    @Override
    public void saveOrdersMongo(List<HisOrders> list) {
        mongoTemplate.insert(list, MongoCollConstants.HIS_ORDERS);
    }

    @Override
    public void delOperDicMongo() {
        mongoTemplate.dropCollection(MongoCollConstants.HIS_OPERATION_DICT);
    }

    @Override
    public void delOperDic() {
        localInfMapper.delOperDic();
    }

    @Override
    public void saveOperDicMongo(List<HisOperationDict> list) {
        mongoTemplate.insert(list, MongoCollConstants.HIS_OPERATION_DICT);
    }

    @Override
    public void saveOperDic(List<HisOperationDict> list) {
        log.info(String.format("insert size :%s", list.size()));
        long start = System.currentTimeMillis();
        List<HisOperationDict> listDic = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getOperationName()))), ArrayList::new));
        jdbcTemplate.batchUpdate("insert into atm_operation_dict(operation_code, operation_name, operation_scale, " +
                "std_indicator, approved_indicator, create_date, input_code) " +
                "        values(?,?,?,?,?,?,?)", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return listDic.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, listDic.get(i).getOperationCode());
                ps.setString(2, listDic.get(i).getOperationName());
                ps.setString(3, listDic.get(i).getOperationScale());
                ps.setObject(4, listDic.get(i).getStdIndicator());
                ps.setObject(5, listDic.get(i).getApprovedIndicator());
                if (listDic.get(i).getCreateDate() != null) {
                    ps.setTimestamp(6, new Timestamp(listDic.get(i).getCreateDate().getTime()));
                } else {
                    ps.setTimestamp(6, null);
                }
                ps.setString(7, listDic.get(i).getInputCode());
            }
        });

        long end = System.currentTimeMillis();

        log.info(String.format("insert oper_dic cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void delScheOperName(List<HisScheduledOperationName> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("delete from ATM_SCHEDULED_OPERATION_NAME where" +
                " PATIENT_ID=? and VISIT_ID=? and SCHEDULE_ID=?", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getPatientId());
                ps.setString(2, list.get(i).getVisitId());
                ps.setString(3, list.get(i).getScheduleId());
            }
        });

        long end = System.currentTimeMillis();
        log.info(String.format("del size :%s", list.size()));
        log.info(String.format("del sche_oper_name cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void saveScheOperName(List<HisScheduledOperationName> list) {
        log.info(String.format("insert size :%s", list.size()));
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into ATM_SCHEDULED_OPERATION_NAME(patient_id, visit_id, schedule_id, " +
                "operation_no, operation, operation_scale, operation_code) " +
                "        values(?,?,?,?,?,?,?)", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getPatientId());
                ps.setString(2, list.get(i).getVisitId());
                ps.setString(3, list.get(i).getScheduleId());
                ps.setString(4, list.get(i).getOperationNo());
                ps.setString(5, list.get(i).getOperation());
                ps.setString(6, list.get(i).getOperationScale());
                ps.setString(7, list.get(i).getOperationCode());
            }
        });

        long end = System.currentTimeMillis();

        log.info(String.format("insert sche_oper_name cost: %s秒", (end - start) / 1000));
    }

    @Override
    public List<HisPatMasterIndex> selPatInfLocal(List<String> patIdList) {
        return localInfMapper.selPatInfByIds(patIdList);
    }

    @Override
    public List<HisPatsInHospital> selPatInHosLocal(List<String> patIdList) {
        return localInfMapper.selPatInHosByIds(patIdList);
    }

    @Override
    public void uptPatInfLocal(List<HisPatMasterIndex> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update ATM_PAT_MASTER_INDEX set name=?, " +
                "name_phonetic=?, " +
                "sex=?, " +
                "date_of_birth=?, birth_place=?, citizenship=?, nation=?, id_no=?, identity=?, charge_type=?, " +
                "mailing_address=?, " +
                "zip_code=?, phone_number_home=?, phone_number_business=?, next_of_kin=?, relationship=?, " +
                "next_of_kin_addr=?, " +
                "next_of_kin_zip_code=?, next_of_kin_phone=?, last_visit_date=?, vip_indicator=?, create_date=?, " +
                "operator=? where patient_id=?", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getName());
                ps.setString(2, list.get(i).getNamePhonetic());
                ps.setString(3, list.get(i).getSex());
                if (list.get(i).getDateOfBirth() != null) {
                    ps.setTimestamp(4, new Timestamp(list.get(i).getDateOfBirth().getTime()));
                } else {
                    ps.setTimestamp(4, null);
                }

                ps.setString(5, list.get(i).getBirthPlace());
                ps.setString(6, list.get(i).getCitizenship());
                ps.setString(7, list.get(i).getNation());
                ps.setString(8, list.get(i).getIdNo());
                ps.setString(9, list.get(i).getIdentity());
                ps.setString(10, list.get(i).getChargeType());
                ps.setString(11, list.get(i).getMailingAddress());
                ps.setString(12, list.get(i).getZipCode());
                ps.setString(13, list.get(i).getPhoneNumberHome());
                ps.setString(14, list.get(i).getPhoneNumberBusiness());
                ps.setString(15, list.get(i).getNextOfKin());
                ps.setString(16, list.get(i).getRelationship());
                ps.setString(17, list.get(i).getNextOfKinAddr());
                ps.setString(18, list.get(i).getNextOfKinZipCode());
                ps.setString(19, list.get(i).getNextOfKinPhone());
                if (list.get(i).getLastVisitDate() != null) {
                    ps.setTimestamp(20, new Timestamp(list.get(i).getLastVisitDate().getTime()));
                } else {
                    ps.setTimestamp(20, null);
                }

                ps.setObject(21, list.get(i).getVipIndicator());
                if (list.get(i).getCreateDate() != null) {
                    ps.setTimestamp(22, new Timestamp(list.get(i).getCreateDate().getTime()));
                } else {
                    ps.setTimestamp(22, null);
                }
                ps.setString(23, list.get(i).getOperator());
                ps.setString(24, list.get(i).getPatientId());
            }
        });

        long end = System.currentTimeMillis();
        log.info(String.format("update size :%s", list.size()));
        log.info(String.format("update pat_inf cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void savePatInfLocal(List<HisPatMasterIndex> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into ATM_PAT_MASTER_INDEX(patient_id, name, name_phonetic, sex, " +
                        "date_of_birth, birth_place, citizenship, nation, id_no, identity, charge_type, " +
                        "mailing_address, " +
                        "zip_code, phone_number_home, phone_number_business, next_of_kin, relationship, " +
                        "next_of_kin_addr, " +
                        "next_of_kin_zip_code, next_of_kin_phone, last_visit_date, vip_indicator, create_date, " +
                        "operator) " +
                        "        values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, list.get(i).getPatientId());
                        ps.setString(2, list.get(i).getName());
                        ps.setString(3, list.get(i).getNamePhonetic());
                        ps.setString(4, list.get(i).getSex());
                        if (list.get(i).getDateOfBirth() != null) {
                            ps.setTimestamp(5, new Timestamp(list.get(i).getDateOfBirth().getTime()));
                        } else {
                            ps.setTimestamp(5, null);
                        }

                        ps.setString(6, list.get(i).getBirthPlace());
                        ps.setString(7, list.get(i).getCitizenship());
                        ps.setString(8, list.get(i).getNation());
                        ps.setString(9, list.get(i).getIdNo());
                        ps.setString(10, list.get(i).getIdentity());
                        ps.setString(11, list.get(i).getChargeType());
                        ps.setString(12, list.get(i).getMailingAddress());
                        ps.setString(13, list.get(i).getZipCode());
                        ps.setString(14, list.get(i).getPhoneNumberHome());
                        ps.setString(15, list.get(i).getPhoneNumberBusiness());
                        ps.setString(16, list.get(i).getNextOfKin());
                        ps.setString(17, list.get(i).getRelationship());
                        ps.setString(18, list.get(i).getNextOfKinAddr());
                        ps.setString(19, list.get(i).getNextOfKinZipCode());
                        ps.setString(20, list.get(i).getNextOfKinPhone());
                        if (list.get(i).getLastVisitDate() != null) {
                            ps.setTimestamp(21, new Timestamp(list.get(i).getLastVisitDate().getTime()));
                        } else {
                            ps.setTimestamp(21, null);
                        }

                        ps.setObject(22, list.get(i).getVipIndicator());
                        if (list.get(i).getCreateDate() != null) {
                            ps.setTimestamp(23, new Timestamp(list.get(i).getCreateDate().getTime()));
                        } else {
                            ps.setTimestamp(23, null);
                        }
                        ps.setString(24, list.get(i).getOperator());
                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("insert size :%s", list.size()));
        log.info(String.format("insert pat_inf cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void uptPatInHosLocal(List<HisPatsInHospital> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update atm_pats_in_hospital set inp_no=?, ward_code=?, dept_code=?," +
                        "bed_no=?, admission_date_time=?," +
                        "adm_ward_date_time=?, doctor_in_charge=?, diagnosis=? where patient_id=? and visit_id=?",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {

                        ps.setString(1, list.get(i).getInpNo());
                        ps.setString(2, list.get(i).getWardCode());
                        ps.setString(3, list.get(i).getDeptCode());
                        ps.setString(4, list.get(i).getBedNo());
                        if (list.get(i).getAdmissionDateTime() != null) {
                            ps.setTimestamp(5, new Timestamp(list.get(i).getAdmissionDateTime().getTime()));
                        } else {
                            ps.setTimestamp(5, null);
                        }
                        if (list.get(i).getAdmWardDateTime() != null) {
                            ps.setTimestamp(6, new Timestamp(list.get(i).getAdmWardDateTime().getTime()));
                        } else {
                            ps.setTimestamp(6, null);
                        }
                        ps.setString(7, list.get(i).getDoctorInCharge());
                        ps.setString(8, list.get(i).getDiagnosis());
                        ps.setString(9, list.get(i).getPatientId());
                        ps.setString(10, list.get(i).getVisitId());
                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("update size :%s", list.size()));
        log.info(String.format("update pat_in_hos cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void savePatInHosLocal(List<HisPatsInHospital> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into atm_pats_in_hospital(patient_id, visit_id, ward_code, " +
                        "dept_code, " +
                        "bed_no, adm_ward_date_time, doctor_in_charge, diagnosis, admission_date_time, inp_no) " +
                        "        values(?,?,?,?,?,?,?,?,?,?)",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, list.get(i).getPatientId());
                        ps.setString(2, list.get(i).getVisitId());
                        ps.setString(3, list.get(i).getWardCode());
                        ps.setString(4, list.get(i).getDeptCode());
                        ps.setString(5, list.get(i).getBedNo());
                        if (list.get(i).getAdmWardDateTime() != null) {
                            ps.setTimestamp(6, new Timestamp(list.get(i).getAdmWardDateTime().getTime()));
                        } else {
                            ps.setTimestamp(6, null);
                        }
                        ps.setString(7, list.get(i).getDoctorInCharge());
                        ps.setString(8, list.get(i).getDiagnosis());
                        if (list.get(i).getAdmissionDateTime() != null) {
                            ps.setTimestamp(9, new Timestamp(list.get(i).getAdmissionDateTime().getTime()));
                        } else {
                            ps.setTimestamp(9, null);
                        }
                        ps.setString(10, list.get(i).getInpNo());
                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("insert size :%s", list.size()));
        log.info(String.format("insert pat_in_hos cost: %s秒", (end - start) / 1000));
    }

    @Override
    public HisOperationSchedule selOperScheMid(AtmOperationScheduleMid atmOperationScheduleMid) {
        return localInfMapper.selOperScheMid(atmOperationScheduleMid);
    }

    @Override
    public void uptOperMidLocal(List<AtmOperationScheduleMid> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("update ATM_OPERATION_SCHEDULE_MID set scheduled_date_time=?,oper_time=?" +
                " where atm_schedule_id=?", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                if (list.get(i).getScheduledDateTime() != null) {
                    ps.setTimestamp(1, new Timestamp(list.get(i).getScheduledDateTime().getTime()));
                } else {
                    ps.setTimestamp(1, null);
                }
                ps.setString(2, list.get(i).getOperTime());
                ps.setString(3, list.get(i).getAtmScheduleId());
            }
        });

        long end = System.currentTimeMillis();
        log.info(String.format("del size :%s", list.size()));
        log.info(String.format("del his_users cost: %s秒", (end - start) / 1000));
    }

    @Override
    public void intOperMidLocal(List<AtmOperationScheduleMid> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into ATM_OPERATION_SCHEDULE_MID(atm_patient_id, atm_visit_id, atm_schedule_id, " +
                        "his_patient_id, his_visit_id, his_schedule_id, scheduled_date_time, oper_time) " +
                        "        values(?,?,?,?,?,?,?,?)",
                new BatchPreparedStatementSetter() {

                    @Override
                    public int getBatchSize() {
                        return list.size();
                    }

                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, list.get(i).getAtmPatientId());
                        ps.setString(2, list.get(i).getAtmVisitId());
                        ps.setString(3, list.get(i).getAtmScheduleId());
                        ps.setString(4, list.get(i).getHisPatientId());
                        ps.setString(5, list.get(i).getHisVisitId());
                        ps.setString(6, list.get(i).getHisScheduleId());
                        if (list.get(i).getScheduledDateTime() != null) {
                            ps.setTimestamp(7, new Timestamp(list.get(i).getScheduledDateTime().getTime()));
                        } else {
                            ps.setTimestamp(7, null);
                        }
                        ps.setString(8, list.get(i).getOperTime());
                    }
                });

        long end = System.currentTimeMillis();
        log.info(String.format("insert size :%s", list.size()));
        log.info(String.format("insert oper_mid cost: %s秒", (end - start) / 1000));
    }

    @Override
    public HisOperationSchedule selOperSche(String patientId,String visitId,String scheduleId) {
        return localInfMapper.selOperSche(patientId,visitId,scheduleId);
    }

    @Override
    public void saveUsersMongo(List<HisUsers> userList) {
        mongoTemplate.insert(userList, MongoCollConstants.HIS_HIS_USERS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUsers(List<HisUsers> list) {
        long start = System.currentTimeMillis();
        jdbcTemplate.batchUpdate("insert into atm_his_users(user_id, user_name, user_dept, input_code, user_job, " +
                "reserved01, create_date, sync_flag, CA_USER_ID)" +
                "        values(?,?,?,?,?,?,?,?,?)", new BatchPreparedStatementSetter() {

            @Override
            public int getBatchSize() {
                return list.size();
            }

            @Override
            public void setValues(PreparedStatement ps, int i)
                    throws SQLException {
                ps.setString(1, list.get(i).getUserId());
                ps.setString(2, list.get(i).getUserName());
                ps.setString(3, list.get(i).getUserDept());
                ps.setString(4, list.get(i).getInputCode());
                ps.setString(5, list.get(i).getUserJob());
                ps.setString(6, list.get(i).getReserved01());
                if (list.get(i).getCreateDate() != null) {
                    ps.setTimestamp(7, new Timestamp(list.get(i).getCreateDate().getTime()));
                } else {
                    ps.setTimestamp(7, null);
                }
                ps.setObject(8, 2);
                ps.setString(9, list.get(i).getCaUserId());
            }
        });

        long end = System.currentTimeMillis();
        log.info("时间差：" + (end - start));
    }

    @Override
    public List<HisOperationSchedule> selOpertScheleLocal(String startTime, String endTime) {
        return localInfMapper.selOpertScheleLocal(startTime, endTime);
    }

}
